package org.jeecg.modules.demo.mes.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.modules.demo.mes.entity.MesMaterialDetails;
import org.jeecg.modules.demo.mes.entity.MesTechnologyProcedureMaterialBom;
import org.jeecg.modules.demo.mes.mapper.MesTechnologyProcedureMaterialBomMapper;
import org.jeecg.modules.demo.mes.service.IMesMaterialDetailsService;
import org.jeecg.modules.demo.mes.service.IMesMaterialService;
import org.jeecg.modules.demo.mes.service.IMesTechnologyProcedureMaterialBomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Description: 工艺工序物料BOM
 * @Author: jeecg-boot
 * @Date: 2022-11-01
 * @Version: V1.0
 */
@Service
public class MesTechnologyProcedureMaterialBomServiceImpl extends ServiceImpl<MesTechnologyProcedureMaterialBomMapper, MesTechnologyProcedureMaterialBom> implements IMesTechnologyProcedureMaterialBomService {

    @Autowired
    private IMesMaterialDetailsService mesMaterialDetailsService;

    /**
     * 保存物料BOM
     *
     * @param mesTechnologyProcedureMaterialBom mesTechnologyProcedureMaterialBom
     * @throws JeecgBootException
     */
    @Override
    @Transactional(readOnly = false,isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)
    public void saveMaterialBom(MesTechnologyProcedureMaterialBom mesTechnologyProcedureMaterialBom) throws JeecgBootException {
        final String id = mesTechnologyProcedureMaterialBom.getId();
        final String materialId = mesTechnologyProcedureMaterialBom.getMaterialId();
        final Integer quantity = mesTechnologyProcedureMaterialBom.getQuantity();
        final Map<String, Object> cxMap = new HashMap<>();
        if (StringUtils.isBlank(id)) {
            //新增（只需要校验剩余量不小于使用数量即可）
            //写入bom表
            this.save(mesTechnologyProcedureMaterialBom);


            cxMap.put("mainId", materialId);
            cxMap.put("materialStatus", "1");
            final List<MesMaterialDetails> mesMaterialDetails = mesMaterialDetailsService.queryMaterialDetailsSelective(cxMap);
            if (mesMaterialDetails == null) {
                throw new JeecgBootException("该物料号已经使用完毕，请调整后再操作");
            }
            final int size = mesMaterialDetails.size();
            if (quantity > size) {
                throw new JeecgBootException("该物料号未使用的还有" + size + "个，请调整使用数量");
            }
            for (int i = 0; i < quantity; i++) {
                final MesMaterialDetails details = mesMaterialDetails.get(i);
                details.setMaterialStatus("2");
                details.setUpdateBy(JwtUtil.getUserName());
                details.setUpdateTime(new Date());
                details.setProcedureMaterialBomId(mesTechnologyProcedureMaterialBom.getId());
                mesMaterialDetailsService.updateById(details);
            }

            return;
        }
        //编辑
        //1.获取现在的使用量
        cxMap.put("mainId", materialId);
        cxMap.put("materialStatus", "2");
        final List<MesMaterialDetails> usedMaterials = mesMaterialDetailsService.queryMaterialDetailsSelective(cxMap);
        //2.比较是增加还是减少了
        int usedSize = 0;
        if (usedMaterials != null) {
            usedSize = usedMaterials.size();
            if (usedSize > quantity) {
                //2.2 减少--更新当前使用量
                for (int i = 0; i < usedSize; i++) {
                    if (i<quantity){
                        continue;
                    }
                    //把其余的置为未用状态
                    final MesMaterialDetails details = usedMaterials.get(i);
                    details.setMaterialStatus("1");
                    details.setUpdateBy(JwtUtil.getUserName());
                    details.setUpdateTime(new Date());
                    details.setProcedureMaterialBomId(null);
                    mesMaterialDetailsService.updateById(details);
                }
            }
        }
        if (usedSize < quantity) {
            //2.1 增加--判断剩余量
            cxMap.put("materialStatus", "1");
            final List<MesMaterialDetails> noUseMaterials = mesMaterialDetailsService.queryMaterialDetailsSelective(cxMap);
            if (noUseMaterials==null){
                throw new JeecgBootException("该物料号已经使用完毕，请调整后再操作");
            }
            int diff = quantity-usedSize;
            final int noUseSize = noUseMaterials.size();
            if (noUseSize<diff){
                throw new JeecgBootException("该物料号未使用的还有" + noUseSize + "个，请调整使用数量");
            }
            for (int i = 0; i < diff; i++) {
                final MesMaterialDetails details = noUseMaterials.get(i);
                details.setMaterialStatus("2");
                details.setUpdateTime(new Date());
                details.setUpdateBy(JwtUtil.getUserName());
                details.setProcedureMaterialBomId(mesTechnologyProcedureMaterialBom.getId());
                mesMaterialDetailsService.updateById(details);
            }

        }
        //3.最后更新bom表
        this.updateById(mesTechnologyProcedureMaterialBom);
    }

    /**
     * 移除物料BOM
     * @param id id
     * @throws JeecgBootException
     */
    @Override
    @Transactional(readOnly = false,isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)
    public void removeProcedureMaterialBomById(String id) throws JeecgBootException {
        mesMaterialDetailsService.resetMaterialDetailByProcedureMaterialBomId(id);
        this.removeById(id);
    }

    @Override
    public List<MesTechnologyProcedureMaterialBom> queryTechnologyProcedureMaterialBomListSelective(Map<String, Object> cxMap) throws JeecgBootException {
        if (cxMap==null){
            return new ArrayList<>();
        }
        return this.baseMapper.queryTechnologyProcedureMaterialBomListSelective(cxMap);
    }

}
